<?php
declare(strict_types=1);

namespace app\common\command;

use app\admin\model\Menus;
use app\common\Attribute\CodeAnalyzer;
use app\admin\model\AuthRule;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\facade\Db;
use think\facade\Filesystem;

class Rule extends Command
{
    protected function configure()
    {
        $this->setName('test:test1')
            ->setDescription('自动生成和更新系统权限节点');
    }

    protected function execute(Input $input, Output $output)
    {
        try {
            // 获取应用目录下的所有应用
            $appPath = root_path() . 'app/';
            $applications = [];

            foreach (scandir($appPath) as $item) {
                if ($item === '.' || $item === '..' || $item === 'common') {
                    continue;
                }

                if (is_dir($appPath . $item) && is_dir($appPath . $item . '/controller')) {
                    $applications[$item] = $appPath . $item . '/controller';
                }
            }

            // 创建分析器实例
            $analyzer = new CodeAnalyzer($applications);

            // 执行分析
            $results = $analyzer->analyze();

            // 开始事务
            Db::startTrans();

            try {
                // 处理分析结果并更新权限节点
                $this->processResults($results, $output);

                // 提交事务
                Db::commit();

                $output->writeln('<info>权限节点更新成功！</info>');
            } catch (\Exception $e) {
                // 回滚事务
                Db::rollback();
                throw $e;
            }

        } catch (\Exception $e) {
            $output->writeln('<error>' . $e->getMessage() . '</error>');
            $output->writeln($e->getTraceAsString());
            return 1;
        }

        return 0;
    }

    /**
     * 处理分析结果并更新权限节点
     */
    private function processResults(array $results, Output $output)
    {
        // 存储已创建的节点ID，用于建立父子关系
        $createdNodes = [];

        foreach ($results as $appName => $controllers) {
            // 第一级节点：应用
            $appNode = $this->createOrUpdateNode([
                'parent_id' => 0,
                'app_name' => $appName,
                'title' => $appName,
                'url' => $appName,
                'method' => null,
                'description' => "应用：$appName",
                'is_need_auth' => 0,
                'is_system' => 1
            ]);

            $createdNodes[$appName] = $appNode['id'];
            $output->writeln("创建应用节点: {$appName} (ID: {$appNode['id']})");

            foreach ($controllers as $namespace => $controller) {
                // 获取控制器名称
                $controllerName = str_replace('\\', '.', substr($namespace, strrpos($namespace, '\\') + 1));

                // 检查控制器是否有ClassTitle属性
                $classAttributes = array_column($controller['attributes'], null, 'name');
                $controllerTitle = $classAttributes['app\\common\\Attribute\\ClassTitle']['arguments'][0] ?? $controllerName;

                // 第二级节点：控制器
                $controllerNode = $this->createOrUpdateNode([
                    'app_name' => $appName,
                    'parent_id' => $createdNodes[$appName],
                    'title' => $controllerTitle,
                    'url' => "{$appName}/{$controllerName}",
                    'method' => null,
                    'description' => "控制器：{$controllerTitle}",
                    'is_need_auth' => 0,
                    'is_system' => 1
                ]);

                $createdNodes[$namespace] = $controllerNode['id'];
                $output->writeln("  创建控制器节点: {$controllerTitle} (ID: {$controllerNode['id']})");

                foreach ($controller['methods'] as $methodName => $method) {
                    // 只处理public方法
                    if (!$method['isPublic']) {
                        continue;
                    }

                    // 获取方法的属性
                    $methodAttributes = array_column($method['attributes'], null, 'name');

                    // 检查是否有RequestMethod和RequestTitle属性
                    if (
                        !isset($methodAttributes['app\\common\\Attribute\\RequestMethod']) ||
                        !isset($methodAttributes['app\\common\\Attribute\\RequestTitle'])
                    ) {
                        continue;
                    }

                    $requestMethods = $methodAttributes['app\\common\\Attribute\\RequestMethod']['arguments'][0][0] ?? '';
                    $requestTitle = $methodAttributes['app\\common\\Attribute\\RequestTitle']['arguments'][0] ?? $methodName;

                    if (empty($requestMethods)) {
                        continue;
                    }

                    // 第三级节点：控制器方法
                    $methodNode = $this->createOrUpdateNode([
                        'app_name' => $appName,
                        'parent_id' => $createdNodes[$namespace],
                        'title' => $requestTitle,
                        'url' => "{$appName}/{$controllerName}/{$methodName}",
                        'method' => null,
                        'description' => "方法：{$requestTitle}",
                        'is_need_auth' => 0,
                        'is_system' => 1
                    ]);

                    $createdNodes["{$namespace}::{$methodName}"] = $methodNode['id'];
                    $output->writeln("    创建方法节点: {$requestTitle} (ID: {$methodNode['id']})");

                    // 解析请求方法（可能有多个）
                    $httpMethods = explode(',', $requestMethods);

                    foreach ($httpMethods as $httpMethod) {
                        $httpMethod = trim($httpMethod);
                        if (empty($httpMethod)) {
                            continue;
                        }

                        // 第四级节点：请求方式
                        $url = "{$appName}/{$controllerName}/{$methodName}";
                        $nodeData = [
                            'app_name' => $appName,
                            'parent_id' => $createdNodes["{$namespace}::{$methodName}"],
                            'title' => "{$requestTitle} ({$httpMethod})",
                            'url' => $url,
                            'method' => $httpMethod,
                            'description' => "请求方式：{$httpMethod} - {$requestTitle}",
                            'is_need_auth' => 1,
                            'is_system' => 1
                        ];
                        $this->createOrUpdateNode($nodeData);
                        // // 检查是否已存在相同的节点
                        // $existingNode = AuthRule::where([
                        //     'parent_id' => $nodeData['parent_id'],
                        //     'url' => $nodeData['url'],
                        //     'method' => $nodeData['method']
                        // ])->find();

                        // if ($existingNode) {
                        //     // 更新现有节点
                        //     $existingNode->save($nodeData);
                        //     $nodeId = $existingNode->id;
                        //     $output->writeln("      更新请求方式节点: {$httpMethod} - {$requestTitle} (ID: {$nodeId})");
                        // } else {
                        //     // 创建新节点
                        //     $newNode = AuthRule::create($nodeData);
                        //     $nodeId = $newNode->id;
                        //     $output->writeln("      创建请求方式节点: {$httpMethod} - {$requestTitle} (ID: {$nodeId})");
                        // }
                    }
                }
            }
        }
    }


    /**
     * 创建或更新节点
     */
    private function createOrUpdateNode(array $data)
    {
        $this->Menus($data);
        return $this->AuthRule($data);

    }


    /**
     * 创建或更新节点
     */
    private function AuthRule(array $data)
    {
        // 检查节点是否已存在
        $where = [
            'parent_id' => $data['parent_id'],
            'url' => $data['url']
        ];

        if (!empty($data['method'])) {
            $where['method'] = $data['method'];
        } else {
            $where['method'] = null;
        }
        unset($data['id']);
        $node = AuthRule::where($where)->findOrEmpty();

        if ($node->isEmpty()) { // 创建新节点
            dump($data);
            $node = AuthRule::create($data);
            // 更新现有节点
            return $node->toArray();
        } else {
            $node->save($data);
            return $node->toArray();
        }
    }

    /**
     * 创建或更新节点
     */
    private function Menus(array $data)
    {

        // 检查节点是否已存在
        $where = [
            'parent_id' => $data['parent_id'],
            'url' => $data['url']
        ];
        $data['method'] = $data['method'] ?? null;

        if (!in_array($data['method'], [null, 'GET'])) {
            return;
        }
        unset($data['method']);

        $node = Menus::where($where)->find();

        if ($node) {
            // 更新现有节点
            $node->save($data);
            return $node->toArray();
        } else {
            // 创建新节点
            $node = Menus::create($data);
            return $node->toArray();
        }
    }
}